package com.miniapp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.miniapp.entity.BaseFile;
import com.miniapp.entity.BusinessFile;
import com.miniapp.mapper.BusinessFileMapper;
import com.miniapp.service.BaseFileService;
import com.miniapp.service.BusinessFileService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 业务文件服务实现类
 *
 * <p>实现文件与业务的关联管理，适配BaseFileService接口变更
 *
 * @author yourName
 * @date 2025-09-06
 */
@Service
public class BusinessFileServiceImpl extends ServiceImpl<BusinessFileMapper, BusinessFile> implements BusinessFileService {

    private static final Logger log = LoggerFactory.getLogger(BusinessFileServiceImpl.class);

    @Autowired
    private BaseFileService baseFileService;

    /**
     * 上传文件并绑定业务
     *
     * <p>直接上传为正式文件并与业务关联
     *
     * @param file 上传的文件
     * @param businessCode 业务编码
     * @param businessType 业务类型
     * @param uploaderId 上传人ID
     * @param sort 排序号
     * @return 业务文件关联实体
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BusinessFile uploadAndBind(MultipartFile file, String businessCode, String businessType,
                                      Long uploaderId, Integer sort) {
        // 校验参数
        validateBusinessParams(businessCode, businessType);

        // 构建正式文件存储目录：按业务类型和编码分类
        String dir = businessType + "/" + businessCode;

        // 上传为正式文件（isTemporary=false）
        BaseFile baseFile = baseFileService.uploadFile(file, false, dir);

        // 创建业务关联
        return createBusinessFileRelation(baseFile, businessCode, businessType, sort);
    }

    /**
     * 将已存在的临时文件绑定到业务（自动转为正式文件）
     *
     * @param fileId 临时文件ID
     * @param businessCode 业务编码
     * @param businessType 业务类型
     * @param sort 排序号
     * @return 业务文件关联实体
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BusinessFile bindExistingFile(Long fileId, String businessCode, String businessType, Integer sort) {
        // 校验参数
        validateBusinessParams(businessCode, businessType);
        if (fileId == null) {
            throw new IllegalArgumentException("文件ID不能为空");
        }

        // 将临时文件转换为正式文件（关联业务目录）
        BaseFile baseFile = baseFileService.convertToFormalFile(fileId, businessType, businessCode);

        // 创建业务关联
        return createBusinessFileRelation(baseFile, businessCode, businessType, sort);
    }

    /**
     * 根据业务信息查询关联的文件列表
     *
     * @param businessCode 业务编码
     * @param businessType 业务类型
     * @return 业务文件列表
     */
    @Override
    public List<BusinessFile> getByBusiness(String businessCode, String businessType) {
        validateBusinessParams(businessCode, businessType);

        LambdaQueryWrapper<BusinessFile> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BusinessFile::getBusinessCode, businessCode)
                .eq(BusinessFile::getBusinessType, businessType)
                .eq(BusinessFile::getIsDeleted, 0)
                .orderByAsc(BusinessFile::getSort);

        return baseMapper.selectList(queryWrapper);
    }

    /**
     * 解除文件与业务的关联
     *
     * @param id 业务文件关联ID
     * @return 是否解除成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean unbind(Long id) {
        if (id == null) {
            throw new IllegalArgumentException("关联ID不能为空");
        }

        BusinessFile businessFile = baseMapper.selectById(id);
        if (businessFile == null) {
            log.warn("解除文件关联失败，关联记录不存在，id: {}", id);
            return false;
        }

        // 逻辑删除关联记录
        businessFile.setIsDeleted(1);
        businessFile.setUpdateTime(LocalDateTime.now());
        int rows = baseMapper.updateById(businessFile);

        return rows > 0;
    }

    /**
     * 批量解除业务与文件的关联
     *
     * @param businessCode 业务编码
     * @param businessType 业务类型
     * @return 解除的数量
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int batchUnbind(String businessCode, String businessType) {
        validateBusinessParams(businessCode, businessType);

        LambdaQueryWrapper<BusinessFile> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BusinessFile::getBusinessCode, businessCode)
                .eq(BusinessFile::getBusinessType, businessType)
                .eq(BusinessFile::getIsDeleted, 0);

        BusinessFile updateEntity = new BusinessFile();
        updateEntity.setIsDeleted(1);
        updateEntity.setUpdateTime(LocalDateTime.now());

        return baseMapper.update(updateEntity, queryWrapper);
    }

    /**
     * 校验业务参数
     *
     * @param businessCode 业务编码
     * @param businessType 业务类型
     */
    private void validateBusinessParams(String businessCode, String businessType) {
        if (businessCode == null || businessCode.trim().isEmpty()) {
            throw new IllegalArgumentException("业务编码不能为空");
        }
        if (businessType == null || businessType.trim().isEmpty()) {
            throw new IllegalArgumentException("业务类型不能为空");
        }
    }

    /**
     * 创建业务文件关联关系
     *
     * @param baseFile 基础文件信息
     * @param businessCode 业务编码
     * @param businessType 业务类型
     * @param sort 排序号
     * @return 业务文件关联实体
     */
    private BusinessFile createBusinessFileRelation(BaseFile baseFile, String businessCode,
                                                    String businessType, Integer sort) {
        BusinessFile businessFile = new BusinessFile();
        businessFile.setBaseFileId(baseFile.getId());
        businessFile.setBusinessCode(businessCode);
        businessFile.setBusinessType(businessType);
        businessFile.setSort(sort != null ? sort : 0);
        businessFile.setCreateTime(LocalDateTime.now());
        businessFile.setUpdateTime(LocalDateTime.now());
        businessFile.setIsDeleted(0);

        baseMapper.insert(businessFile);

        log.info("文件与业务绑定成功，fileId: {}, businessType: {}, businessCode: {}",
                baseFile.getId(), businessType, businessCode);

        return businessFile;
    }
}
